package ibm.cognos.imt;

import com.cognos.developer.schemas.bibus._3.*;
import org.apache.axis.AxisFault;
import org.apache.axis.client.Stub;

import javax.xml.rpc.ServiceException;
import java.net.MalformedURLException;
import java.net.URL;

public class ReportRunner {
    public static String replaceSubstring(
            String str,
            String pattern,
            String replace)
    {
        int strLen = str.length();
        int patternLen = pattern.length();
        int start = 0, end = 0;
        StringBuffer result = new StringBuffer(strLen);
        char[] chars = new char[strLen];

        while ((end = str.indexOf(pattern, start)) >= 0)
        {
            str.getChars(start, end, chars, 0);
            result.append(chars, 0, end - start).append(replace);
            start = end + patternLen;
        }

        str.getChars(start, strLen, chars, 0);
        result.append(chars, 0, strLen - start);

        return result.toString();
    }

    static void setUpHeader(
            ReportService_PortType repService,
            String user,
            String pass,
            String name) {
        // Scrub the header to remove the conversation context.
        BiBusHeader bibus =
                BIBusHeaderHelper.getHeaderObject(((Stub) repService).getResponseHeader("", "biBusHeader"));

        if (bibus != null) {
            if (bibus.getTracking() != null) {
                if (bibus.getTracking().getConversationContext() != null) {
                    bibus.getTracking().setConversationContext(null);
                }
            }

            return;
        }

        // Set up a new biBusHeader for the "logon" action.
        bibus = new BiBusHeader();
        bibus.setCAM(new CAM());
        bibus.getCAM().setAction("logonAs");
        bibus.setHdrSession(new HdrSession());

        FormFieldVar ffs[] = new FormFieldVar[3];

        ffs[0] = new FormFieldVar();
        ffs[0].setName("CAMUsername");
        ffs[0].setValue(user);
        ffs[0].setFormat(FormatEnum.not_encrypted);

        ffs[1] = new FormFieldVar();
        ffs[1].setName("CAMPassword");
        ffs[1].setValue(pass);
        ffs[1].setFormat(FormatEnum.not_encrypted);

        ffs[2] = new FormFieldVar();
        ffs[2].setName("CAMNamespace");
        ffs[2].setValue(name);
        ffs[2].setFormat(FormatEnum.not_encrypted);

        bibus.getHdrSession().setFormFieldVars(ffs);

        ((Stub) repService).setHeader("http://developer.cognos.com/schemas/bibus/3/", "biBusHeader", bibus);
    }

//    private static String generateReport(CogReport report, BiServerConfig config, Option[] runOptions) {
//        {
//            // Specify a user to log in as.
//            String userName = "";
//            String userPassword = "";
//            String userNamespace = "";
//
//
//            // Create a connection to a report server.
////        String Cognos_URL =
////                "http://"
////                        + serverHost
////                        + ":"
////                        + serverPort
////                        + "/p2pd/servlet/dispatch";
//
////        System.out.println("Server URL: " + Cognos_URL);
//            ReportService_ServiceLocator reportServiceLocator =
//                    new ReportService_ServiceLocator();
//
//            ReportService_PortType repService = null;
//
//            try {
////            repService = reportServiceLocator.getreportService(new URL(Cognos_URL));
//                repService = reportServiceLocator.getreportService(new URL((String) (report.getBiServerUrl())));
//            } catch (MalformedURLException ex) {
//                System.out.println("Caught a MalformedURLException:" + ex.getMessage());
//                System.exit(-1);
//            } catch (ServiceException ex) {
//                System.out.println("Caught a ServiceException: " + ex.getMessage());
//                ex.printStackTrace();
//                System.exit(-1);
//            }
//
//            System.out.println("... done.");
//
//            // Set up the biBusHeader for a logon.
//            if ((userName.length() > 0)
//                    && (userPassword.length() > 0)
//                    && (userNamespace.length() > 0)) {
//                System.out.println(
//                        "Logging on as "
//                                + userName
//                                + " in the "
//                                + userNamespace
//                                + " namespace.");
//                setUpHeader(repService, userName, userPassword, userNamespace);
//            }
//
//            // Set up the report parameters.
//            ParameterValue parameters[] = new ParameterValue[]{};
//
////        Option runOptions[] = new Option[5];
////
////        RunOptionBoolean saveOutput = new RunOptionBoolean();
////        saveOutput.setName(RunOptionEnum.saveOutput);
////        saveOutput.setValue(false);
////        runOptions[0] = saveOutput;
////
////        // TODO: Output format should be specified on the command-line
////        RunOptionStringArray outputFormat = new RunOptionStringArray();
////        outputFormat.setName(RunOptionEnum.outputFormat);
////        outputFormat.setValue(new String[] { "HTML" });
////        runOptions[1] = outputFormat;
////
////        RunOptionOutputEncapsulation outputEncapsulation =
////                new RunOptionOutputEncapsulation();
////        outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
////        outputEncapsulation.setValue(OutputEncapsulationEnum.none);
////        runOptions[2] = outputEncapsulation;
////
////        AsynchOptionInt primaryWait = new AsynchOptionInt();
////        primaryWait.setName(AsynchOptionEnum.primaryWaitThreshold);
////        primaryWait.setValue(0);
////        runOptions[3] = primaryWait;
////
////        AsynchOptionInt secondaryWait = new AsynchOptionInt();
////        secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
////        secondaryWait.setValue(0);
////        runOptions[4] = secondaryWait;
//
//            String[] data = null;
//
//            // Now, run the report.
//            try {
//                System.out.println("Running the report...");
////			System.out.println("Report search path is:");
////			System.out.println(reportPath);
//
////			AsynchReply res =
////                repService.run(new SearchPathSingleObject(reportPath), parameters, runOptions);
//
//                ReportServiceSpecification metadataSpec = new ReportServiceReportSpecification();
//                metadataSpec.setValue(new Specification((String) report.generateSpec()));
//
//                AsynchReply res =
//                        repService.runSpecification(metadataSpec, parameters, runOptions);
//
//                System.out.println("... done.");
//
//                // The report is finished, let's fetch the results and save them to
//                // a file.
//                if (res.getStatus() == AsynchReplyStatusEnum.complete)
//
//                {
//                    AsynchDetailReportOutput reportOutput = null;
//
//                    for (int i = 0; i < res.getDetails().length; i++) {
//                        if (res.getDetails()[i]
//                                instanceof AsynchDetailReportOutput) {
//                            reportOutput =
//                                    (AsynchDetailReportOutput) res.getDetails()[i];
//                            break;
//                        }
//                    }
//
//                    String[] pages = reportOutput.getOutputPages();
//                    data = new String[pages.length];
//                    for (int i = 0; i < data.length; i++) {
//                        data[i] = replaceSubstring(pages[i], "../", (String) report.getResourceUrl());      //"http://" + serverHost + ":" + gatewayPort + "/ibmcognos/"
//                        data[i] = replaceSubstring(data[i], "src=\"?", "src=\"http://" + report.getResourceUrl()+"/cgi-bin/cognos.cgi?");
//                    }
//
////                System.out.println(
////                        "Writing report output to " + outputPath + "...");
////                FileOutputStream fs = new FileOutputStream(outputPath);
////
////                // URIs in the output are relative on the server; we need to
////                // make them absolute so they reference the server properly.
////				String uriFix =
////					"http://" + serverHost + ":" + serverPort + "/ibmcognos/";
////
////                String uriFix =
////                        "http://" + serverHost + "/ibmcognos/";
////
////                for (int idx = 0; idx < data.length; idx++)
////                {
////                    String fixed_hunk =
////                            replaceSubstring(data[idx], "../", uriFix);
//////                    fs.write(fixed_hunk.getBytes());
////                }
////
////                fs.close();
////                System.out.println("... done.");
//                }
//            } catch (AxisFault ex) {
//                String ex_str = CognosBIException.convertToString(ex);
//                System.out.println("SOAP exception!");
//                System.out.println(ex_str);
//            } catch (Exception ex) {
//                System.out.println("Unhandled exception!");
//                System.out.println("Message: " + ex.getMessage());
//                System.out.println("Stack trace:");
//                ex.printStackTrace();
//            }
//            return data[0];
//        }
//    }

    public static String[] runReport(String reportSpecString) {
        try {

            String Cognos_URL = "http://192.168.116.128:88/p2pd/servlet/dispatch";

//            String Cognos_URL = "http://9.119.141.62:8080/p2pd/servlet/dispatch";

            ReportService_ServiceLocator reportServiceLocator = new ReportService_ServiceLocator();

            ReportService_PortType repService = null;

            try {
                repService = reportServiceLocator.getreportService(new URL(Cognos_URL));
            } catch (MalformedURLException ex) {
                System.out.println("Caught a MalformedURLException:" + ex.getMessage());
                System.out.println("Server URL was: " + Cognos_URL);
                System.exit(-1);
            } catch (ServiceException ex) {
                System.out.println("Caught a ServiceException: " + ex.getMessage());
                ex.printStackTrace();
                System.exit(-1);
            }
            System.out.println("Running the report...");

            ReportServiceSpecification metadataSpec = new ReportServiceReportSpecification();
            metadataSpec.setValue(new Specification(reportSpecString));

            AsynchReply res = repService.runSpecification(metadataSpec, getParameters(), getRunOptions());

            // The report is finished, let's fetch the results and save them to a file.
            if (res.getStatus() == AsynchReplyStatusEnum.complete) {
                AsynchDetailReportOutput reportOutput = null;

                for (int i = 0; i < res.getDetails().length; i++) {
                    if (res.getDetails()[i]
                            instanceof AsynchDetailReportOutput) {
                        reportOutput = (AsynchDetailReportOutput) res.getDetails()[i];
                        break;
                    }
                }

                return reportOutput.getOutputPages();
            }
        } catch (AxisFault ex) {

            ex.printStackTrace();
        } catch (Exception ex) {

            ex.printStackTrace();
        }
        return null;

    }

    private static ParameterValue[] getParameters() {
        return new ParameterValue[]{};
    }

    private static Option[] getRunOptions() {


        Option runOptions[] = new Option[6];

        RunOptionBoolean saveOutput = new RunOptionBoolean();
        saveOutput.setName(RunOptionEnum.saveOutput);
        saveOutput.setValue(false);
        runOptions[0] = saveOutput;

        // TODO: Output format should be specified on the command-line
        RunOptionStringArray outputFormat = new RunOptionStringArray();
        outputFormat.setName(RunOptionEnum.outputFormat);
        outputFormat.setValue(new String[]{"HTML"});
        runOptions[1] = outputFormat;

        RunOptionOutputEncapsulation outputEncapsulation =
                new RunOptionOutputEncapsulation();
        outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
        outputEncapsulation.setValue(OutputEncapsulationEnum.none);
        runOptions[2] = outputEncapsulation;

        AsynchOptionInt primaryWait = new AsynchOptionInt();
        primaryWait.setName(AsynchOptionEnum.primaryWaitThreshold);
        primaryWait.setValue(0);
        runOptions[3] = primaryWait;

        AsynchOptionInt secondaryWait = new AsynchOptionInt();
        secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
        secondaryWait.setValue(0);
        runOptions[4] = secondaryWait;

        RunOptionInt runOpt = new RunOptionInt();
        runOpt.setName(RunOptionEnum.verticalElements);
        runOpt.setValue(0);
        runOptions[5] = runOpt;

        return runOptions;
    }


}
